package com.InterestingExercises.ATM_Project;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class ATM {
    //用户账户对象ArrayList
    private ArrayList<Account> accounts = new ArrayList<>();
    private Scanner sc = new Scanner(System.in);
    private Account acc;//用于登录后存储登录者的信息


    /**
     * 启动函数
     */
    public void start() {
        boolean flag = true;
        while (flag) {
            System.out.println("+-----------------+");
            System.out.println("|  欢迎您进入ATM系统 |");
            System.out.println("|  1.开户号直接登录  |");
            System.out.println("|  2.其他用户登录    |");
            System.out.println("|  3.用户开户       |");
            System.out.println("|  4.退出系统       |");
            System.out.println("+-----------------+");
            System.out.println("请选择:");
            int command = sc.nextInt();
            switch (command) {
                case 1:
                    System.out.println("+------------------------+");
                    //开户号直接登录
                    if (acc == null) {
                        System.out.println("\n无法直接登录,请先开户!\n");
                    } else {
                        System.out.println(acc.getUserName() + ",恭喜您登录成功!\n您的卡号是[  " + acc.getCardId() + "  ]");
                        showUserCommand();
                    }
                    break;
                case 2:
                    System.out.println("+------------------------+");
                    //用户登录
                    login();
                    break;
                case 3:
                    //用户开户
                    System.out.println("+--------------+");
                    System.out.println("|    进入开户   |");
                    System.out.println("+--------------+");
                    createAccount();

                    /*for (int i = 0; i < accounts.size(); i++) {
                        System.out.println(accounts.get(i).toString());//测试用
                    }*/

                    break;
                case 4:
                    //退出系统
                    System.out.println("+--------------+");
                    System.out.println("| 谢谢使用,再见~ |");
                    System.out.println("+--------------+");
                    flag = false;
                    break;
                default:
                    System.out.println("+----------------+");
                    System.out.println("| 没有该操作,请重输 |");
                    System.out.println("+----------------+");
            }
        }
    }

    /**
     * 开户后直接登录功能
     */
    private void immediateLogin() {

    }


    /**
     * 登录功能
     */
    private void login() {
        //1.判断系统中是否存在账户对象,存在才能登陆,如果不存在直接结束登录操作
        if (accounts.size() == 0) {
            //说明一个账户都没有,没必要继续登录了
            System.out.println("\n系统中还没有账户,请先开户!\n");
            return;
        }
        //2.输入卡号
        while (true) {
            System.out.println("请输入您的登录卡号:");
            String cardId = sc.next();
            //3.判断卡号是否存在
            Account account = getAccountByCardId(cardId);
            if (account == null) {
                System.out.println("您输入的卡号不存在,请确认!");
            } else {
                while (true) {
                    //4.提示输入密码
                    System.out.println("请输入登录密码:");
                    String password = sc.next();
                    if (account.getPassword().equals(password)) {
                        //说明密码正确,登陆成功
                        System.out.println("+------------------------+");
                        System.out.println(account.getUserName() + ",恭喜您登录成功!您的卡号是[  " + cardId + "  ]");
                        acc = account;
                        showUserCommand();
//////////////////////////////////////////////////
                        return;//退出登录,回到第一个界面
                    } else {
                        //密码错误
                        System.out.println("请输入的密码不正确,请确认!");
                    }
                }
            }
        }
    }

    /**
     * 登录成功后显示功能菜单
     */
    private void showUserCommand() {
        while (true) {
            System.out.println("+------------------------+");
            System.out.println("| " + acc.getUserName() + "您可以选择如下功能 |");
            System.out.println("+------------------------+");
            System.out.println("1.查询账户");
            System.out.println("2.存款");
            System.out.println("3.取款");
            System.out.println("4.转账");
            System.out.println("5.密码修改");
            System.out.println("6.退出登录");
            System.out.println("7.注销当前账户");
            System.out.println("+------------------------+");
            System.out.print("请选择:");
            int command = sc.nextInt();
            switch (command) {
                case 1:
                    //                1.查询账户
                    showLoginAccount();
                    break;
                case 2:
                    //                2.存款
                    depositMoney();
                    break;
                case 3:
                    //                3.取款
                    drawMoney();
                    break;
                case 4:
                    //                4.转账
                    transferMoneyToOtherAccount();
                    break;
                case 5:
                    //                5.密码修改
                    updatePassword();
                    acc = null;
                    return;
                case 6:
                    //                6.退出登录
                    System.out.println("+------------------------+");
                    System.out.println("退出登录成功!");
                    acc = null;
                    return;
                case 7:
                    //                7.注销当前账户
                    if (deleteAccount()) {
                        //销户成功
                        acc = null;
                        return;
                    }
                    //销户失败
                    break;
                default:
                    System.out.println("您当前选择的操作是不存在的,请确认!");
            }
        }
    }

    /**
     * 修改密码
     */
    private void updatePassword() {
        System.out.println("==账户密码修改操作==");
        while (true) {
            System.out.println("请您输入当前账户的密码:");
            String password = sc.next();
            if (acc.getPassword().equals(password)) {
                //认证通过
                System.out.println("请您输入新密码:");
                String newPassword = sc.next();
                System.out.println("请您确认密码:");
                String okPassword = sc.next();
                if (newPassword.equals(okPassword)) {
                    acc.setPassword(okPassword);
                    System.out.println("恭喜您,您的密码修改成功!");
                    return;
                } else {
                    System.out.println("您两次输入的密码不一致!");
                }
            } else {
                System.out.println("您当前输入的密码不正确!");
            }
        }
    }

    /**
     * 注销账户
     */
    private boolean deleteAccount() {
        System.out.println("===进行销户操作===");
        System.out.println("请问您确认销户吗?(Y/N)");
        String command = sc.next();
        switch (command) {
            case "Y":
                //确实要销户
                if (acc.getBalance() == 0) {
                    //真的销户了
                    accounts.remove(acc);
                    System.out.println("您好,您的账户已经成功销户了");
                    return true;
                } else {
                    System.out.println("对不起,您的账户中存在金额,不允许销户");
                    return false;
                }
            default:
                System.out.println("好的,您的账户保留");
                return false;
        }
    }

    /**
     * 转账功能
     */
    private void transferMoneyToOtherAccount() {
        System.out.println("+------------------------+");
        System.out.println("开始转账");
        System.out.println("+------------------------+");
        if (accounts.size() == 1) {
            System.out.println("当前系统中只有1个账户,无法转账,请先退出当前账户,再创建其他账户!");
            return;
        }
        if (acc.getBalance() == 0) {
            System.out.println("您自己都没钱就别转了吧~~");
            return;
        }

        System.out.println("请您输入对方的卡号:");
        String targetCardId = sc.next();
        Account targetAccount = getAccountByCardId(targetCardId);
        if (targetAccount == null) {
            System.out.println("您输入的对方卡号有误,请重试!");
            return;
        }
        System.out.println("请输入对方账户[  *" + targetAccount.getUserName().substring(1) + "  ]的户主姓氏:");
        String targetFirstName = sc.next();
        if (!targetAccount.getUserName().startsWith(targetFirstName)) {
            System.out.println("您认证的姓氏有问题,请重试!");
            return;
        }
        System.out.println("请您输入要转给对方的金额:");
        double money = sc.nextDouble();
        if (money <= 0) {
            System.out.println("您输入的金额不合适,请重试!");
            return;
        } else if (money > acc.getBalance()) {
            System.out.println("您的余额是: " + acc.getBalance() + " 元,您输入的金额超过了您的余额,请重试!");
            return;
        } else {
            //合法,开始转账
            acc.setBalance(acc.getBalance() - money);
            targetAccount.setBalance(targetAccount.getBalance() + money);
            System.out.println("转账成功!您现在的余额为 " + acc.getBalance() + " 元");
        }
    }

    /**
     * 取款功能
     */
    private void drawMoney() {
        System.out.println("+------------------------+");
        System.out.println("开始取款");
        System.out.println("+------------------------+");

        if (acc.getBalance() < 100) {
            System.out.println("您的账户余额不足 100 元,不能通过ATM机取款,请去柜台咨询!");
            return;
        }
        System.out.println("请输入取款金额:");
        double money = sc.nextDouble();
        if (money > acc.getBalance()) {
            System.out.println("您的余额为: " + acc.getBalance() + " 元,输入的金额超过了您的余额,请重试!");
            return;
        }
        if (money > acc.getQuota()) {
            System.out.println("您每次的取款限额为: " + acc.getQuota() + " 元,您输入的金额超过了您每次的取款金额,请重试");
            return;
        }
        acc.setBalance(acc.getBalance() - money);//更新余额 由于acc指向accounts中的用户账户对象,因此对acc操作,就是对集合中的对象操作
        System.out.println("+------------------------+");
        System.out.println(acc.getUserName() + "恭喜您取款成功,您现在的余额为: " + acc.getBalance() + " 元");
    }

    /**
     * 存钱功能
     */
    private void depositMoney() {
        System.out.println("+------------------------+");
        System.out.println("进入存款功能");
        System.out.println("+------------------------+");
        while (true) {
            System.out.println("请输入存款金额:");
            double money = sc.nextDouble();
            if (money <= 0) {
                System.out.println("输入金额无效,请重输!");
            } else {
                //表示输入金额有效
                acc.setBalance(acc.getBalance() + money);//更新余额 由于acc指向accounts中的用户账户对象,因此对acc操作,就是对集合中的对象操作
                System.out.println("+------------------------+");
                System.out.println(acc.getUserName() + "恭喜您,您存款 " + money + " 元成功!现在您的余额为: " + acc.getBalance() + " 元");
                break;
            }
        }
    }

    /**
     * 展示登录账户具体信息
     */
    private void showLoginAccount() {
        System.out.println("+------------------------+");
        System.out.println("当前账户信息如下:");
        System.out.println("卡号:" + acc.getCardId());
        System.out.println("户主:" + acc.getUserName());
        System.out.println("性别:" + acc.getGender());
        System.out.println("余额:" + acc.getBalance());
        System.out.println("每次取现额度:" + acc.getQuota());

    }


    /**
     * 开户功能
     */
    private void createAccount() {
        //1.创建一个Account对象用于封装用户的开户信息
        Account account = new Account();
        //2.让用户输入账户信息,赋值给Account对象
        System.out.println("请您输入您的账户名称:");
        String name = sc.next();
        account.setUserName(name);

        while (true) {
            System.out.println("请您输入您的性别:");
            char gender = sc.next().charAt(0);
            if (gender == '男' || gender == '女') {
                account.setGender(gender);
                break;
            } else
                System.out.println("您输入的性别有误,只能是男或女!");
        }

        while (true) {
            System.out.println("请您输入您的账户密码:");
            String password = sc.next();
            System.out.println("请您再次输入您的账户密码:");
            if (!sc.next().equals(password)) {
                System.out.println("两次密码输入不同,请重试!");
                continue;
            }
            account.setPassword(password);
            break;
        }

        double quota;
        while (true) {
            System.out.println("请您输入您的取现额度:");
            quota = sc.nextDouble();
            if (quota > 0) {
                account.setQuota(quota);
                break;
            }
            System.out.println("额度只能为正数,请重试!");
        }


        //为账户自动生成8位数字的卡号,且不能与其他已有的账户重复
        String cardId = generateCardId();
        account.setCardId(cardId);

        //3.把Account对象添加到账户集合中
        accounts.add(account);
        acc = account;//用于实现注册后便捷登录

        System.out.println(account.getUserName() + "的卡号为\n[  " + cardId + "  ]\n的新账户开户成功!");
    }

    /**
     * 为账户自动生成8位数字的卡号,且不能与其他已有的账户重复
     *
     * @return String
     */
    private String generateCardId() {
        Random rd = new Random();
        StringBuilder sb = new StringBuilder();

        String result = null;
        while (true) {
            sb.delete(0, sb.length());//清空StringBuilder
            for (int i = 0; i < 8; i++) {
                sb.append(rd.nextInt(10));
            }
            result = sb.toString();
            //判断生成的cardId是否与已有的cardId重复
            if (getAccountByCardId(result) == null) {
                //说明不重复
                break;
            }
        }
        return result;
    }

    /**
     * 根据cardId查询Account对象
     *
     * @param cardId
     * @return Account
     */
    private Account getAccountByCardId(String cardId) {
        for (int i = 0; i < accounts.size(); i++) {
            if (accounts.get(i).getCardId().equals(cardId)) {
                return accounts.get(i);
            }
        }
        return null;//查无此人
    }


}
